﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;

namespace PingTool
{
    public partial class Form1 : Form
    {
        readonly Dictionary<string, CancellationTokenSource> _tokens = new Dictionary<string, CancellationTokenSource>();

        bool _pingSuccessLog = false;
        bool _pingWriteSuccessLog = false;
        int _pingInterval = 3000;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            RefreshIPControl();
        }

        private void RefreshIPControl()
        {
            foreach (var item in this.flowLayoutPanel1.Controls)
            {
                for (int i = 0; i < 256; i++)
                {
                    if (((Label)item).Name == $"label{i}")
                    {
                        ((Label)item).Text = i.ToString();
                    }
                }
            }
        }

        private void GetLocalIPAll()
        {

        }

        private Color GetStatus(PingReply pr)
        {
            Color status = default(Color);
            if (pr.Status == IPStatus.Success)
            {
                if (pr.RoundtripTime < 50)
                {
                    status = Color.Green;
                }
                else if (50 < pr.RoundtripTime && pr.RoundtripTime < 100)
                {
                    status = Color.Yellow;
                }
                else if (100 < pr.RoundtripTime)
                {
                    status = SystemColors.InactiveCaption;
                }
            }
            else
            {
                status = Color.Silver;
            }
            return status;
        }

        private List<string> GetIP()
        {
            List<string> list = new List<string>();
            for (int i = 0; i < 256; i++)
            {
                string ip = this.txtIP.Text + "." + this.textBox1.Text + "." + this.textBox2.Text + "." + i.ToString();
                list.Add(ip);
            }
            return list;
        }

        private string AddressValidation(string address)
        {
            bool result = default(bool);
            if (int.TryParse(address, out int value))
            {
                if (0 <= value && value < 256)
                {
                    result = true;
                }
                else
                {
                    result = false;
                }
            }
            else
            {
                result = false;
            }
            if (!result)
            {
                new MyMessageBox().ShowBox("请输入0-255范围内的整数");
                address = string.Empty;
            }
            return address;
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            btnStart.Enabled = false;

            _pingInterval = (int)numPingInterval.Value;

            List<string> list = GetIP();
            list.ForEach(ip =>
            {
                var source = new CancellationTokenSource();
                var token = source.Token;

                _tokens.Add(ip, source);

                Task.Run(async () =>
                {
                    var ping = new Ping();

                    while (true)
                    {
                        if (token.IsCancellationRequested) return;

                        // 最多等待3秒
                        var pr = ping.Send(ip, 3000);

                        Color status = GetStatus(pr);

                        string iplab = ip.Split('.').Last();
                        Label lab = (Label)(this.flowLayoutPanel1.Controls.Find($"label{iplab}", false).First());
                        this.Invoke(new Action(() =>
                        {
                            lab.BackColor = status;
                        }));

                        await Task.Delay(_pingInterval);
                    }
                });
            });

            btnStop.Enabled = true;
        }

        private void btnStop_Click(object sender, EventArgs e)
        {
            btnStop.Enabled = false;
            foreach (var kv in _tokens)
            {
                kv.Value.Cancel();
            }

            _tokens.Clear();
            btnStart.Enabled = true;
        }

        private void txtIP_TextChanged(object sender, EventArgs e)
        {
            if (!string.IsNullOrEmpty(this.txtIP.Text))
                this.txtIP.Text = AddressValidation(this.txtIP.Text);
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {
            if (!string.IsNullOrEmpty(this.textBox1.Text))
                this.textBox1.Text = AddressValidation(this.textBox1.Text);
        }

        private void textBox2_TextChanged(object sender, EventArgs e)
        {
            if (!string.IsNullOrEmpty(this.textBox2.Text))
                this.textBox2.Text = AddressValidation(this.textBox2.Text);
        }
    }
}
